﻿using System;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
using BridgeShips.GUISystem;
using Framework.Common;
using BridgeShips.AI;

namespace BridgeShips
{
	/// <summary>
	///
	/// </summary>
	public class InventoryController : MonoSingleton<InventoryController>
	{
		/// <summary></summary>
		public Value_T<ET.InventoryState> State = new Value_T<ET.InventoryState>(ET.InventoryState.Closed);

		/// <summary></summary>
		public Attempt<ET.InventoryState> SetState = new Attempt<ET.InventoryState>();


		/// <summary></summary>
		public Message<ItemHolder> EquipmentChanged = new Message<ItemHolder>(); 

		/// <summary>Is the inventory closed?</summary>
		public bool IsClosed { get { return State.Is(ET.InventoryState.Closed); } }

		/// <summary>Stores all the item and recipe definitions.</summary>
		public ItemDatabase Database { get { return m_ItemDatabase; } }

		//[SerializeField]
		//[Tooltip("The inventory cannot function without this, as some operations, like ADD, LOAD require a database.")]
		private ItemDatabase m_ItemDatabase = null;

        [Header("Item Drop")]

		[SerializeField]
		private Vector3 m_DropOffset = new Vector3(0f, 0f, 0.8f);

		private float m_LastTimeToggledInventory;

		private List<ItemHolder> m_InventoryCollection;
		private List<ItemHolder> m_HotbarCollection;
		private List<ItemHolder> m_EquipmentHolders;


		/// <summary>
		/// Tries to add an amount of items in a certain collection.
		/// </summary>
		/// <param name="itemID"> The name of the item you want to add. </param>
		/// <param name="amount"> How many items of this type you want to add?. </param>
		/// <param name="collection"> Name the collection in which you want the item to be added, eg."Inventory". </param>
		/// <param name="added"> This value represents the amount of items were added, if the collection was almost full, some of the items might've not been added. </param>
		public bool AddItemToCollection(int itemID, int amount, string collection, out int added)
		{
			added = 0;

			if(!enabled)
				return false;

			Debug.LogWarningFormat(this, "No collection with the name '{0}' was found! No item added.", collection);
			return false;
		}

		/// <summary>
		/// Tries to add an amount of items in a certain collection.
		/// </summary>
		/// <param name="itemID">The id of the item you want to add.</param>
		/// <param name="amount">How many items of this type you want to add?.</param>
		/// <param name="collection">Name the collection in which you want the item to be added, eg."Inventory".</param>
		/// <param name="added">This value represents the amount of items were added, if the collection was almost full, some of the items might've not been added.</param>
		public bool AddItemToCollection(string itemName, int amount, string collection, out int added)
		{
			added = 0;

			if(!enabled)
				return false;

			
			Debug.LogWarningFormat(this, "No collection with the name '{0}' was found! No item added.", collection);
			return false;
		}

		public int GetItemCount(string name)
		{
			// TODO: We shouldn't have access to GUI functions here.
			return 0;
		}

		/// <summary>
		/// Removes the item if it exists in the inventory, if not, the method will return false.
		/// </summary>
		public bool TryRemoveItem(SavableItem item)
		{
			if(!enabled)
				return false;
			
			return false;
		}

		public void RemoveItems(string itemName, int amount = 1)
		{
			// TODO: We shouldn't have access to GUI functions here.
		
		}

		public List<ItemHolder> GetEquipmentHolders()
		{
			return m_EquipmentHolders;
		}

		private void Awake()
		{
		}

		

		private void On_PlayerDeath()
		{
			
		}

		private void RemoveItemsFromCollection(string collection)
		{
			// TODO: We shouldn't have access to GUI functions here.
		
		}

		private void DropItemsFromCollection(string collection)
		{
			
		}

		private bool TryChange_State(ET.InventoryState state)
		{
			bool stateWasChanged = false;

			if(Time.time > m_LastTimeToggledInventory + 0.5f)
			{
				m_LastTimeToggledInventory = Time.time;
				stateWasChanged = true;
			}
				
			if(stateWasChanged)
			{
				State.Set(state);
				UnityEngine.EventSystems.EventSystem.current.SetSelectedGameObject(null);
			}

			return stateWasChanged;
		}

		private List<ItemHolder> CreateListOfHolders(int size)
		{
			var slots = new List<ItemHolder>();

			for(int i = 0;i < size;i ++)
				slots.Add(new ItemHolder());

			return slots;
		}
	}
}
